import Func from "@/common/function.js";
import Api from "@/common/api.js";
import Vue from 'vue';

module.exports = {
  dbName: 'main', // 数据库名称
  dbPath: '_doc/wms.db', // 数据库地址,推荐以下划线为开头  
  qtyDecimal:2,//默认小数后2位
  myconfig:uni.getStorageSync('myconfig'),
  user:uni.getStorageSync('user'),
  default_stock_id:0,
  // 判断数据库是否打开
  isOpen() {
    // 数据库打开了就返回 true,否则返回 false
    var open = plus.sqlite.isOpenDatabase({
      name: this.dbName,  // 数据库名称
      path: this.dbPath  // 数据库地址
    })
	this.qtyDecimal = Vue.prototype.globalData.qtyDecimal
	this.default_stock_id = Vue.prototype.globalData.default_stock_id
	
	if(this.qtyDecimal==undefined){
		this.qtyDecimal = 2;
	}
	if(this.default_stock_id==undefined||this.default_stock_id==''){
		Api.msg('默认仓库数据异常')
	}
	
    return open;
  },

//测试专用
test(){
	return new Promise((resolve, reject) => {
	   throw({message:'12345'})
	})
},
  // 创建数据库 或 有该数据库就打开
  openSqlite() {
    return new Promise((resolve, reject) => {
      // 打开数据库
      plus.sqlite.openDatabase({
        name: this.dbName,
        path: this.dbPath,
        success(e) {
          resolve(e); // 成功回调
        },
        fail(e) {
          reject(e);  // 失败回调
        }
      })
    })
  },

  // 关闭数据库
  closeSqlite() {
    return new Promise((resolve, reject) => {
      plus.sqlite.closeDatabase({
        name: this.dbName,
        success(e) {
          resolve(e);
        },
        fail(e) {
          reject(e);
        }
      })
    })
  },

  // 数据库建表 sql:'CREATE TABLE IF NOT EXISTS dbTable("id" varchar(50),"name" TEXT) 
  // 创建 CREATE TABLE IF NOT EXISTS 、 dbTable 是表名，不能用数字开头、括号里是表格的表头
  createTable(dbTable, data) {
    return new Promise((resolve, reject) => {
      // executeSql: 执行增删改等操作的SQL语句
      plus.sqlite.executeSql({
        name: this.dbName,
        sql: `CREATE TABLE IF NOT EXISTS ${dbTable}(${data})`,
        success(e) {
          resolve(e);
        },
        fail(e) {
          reject(e);
        }
      })
    })
  },

  // 数据库删表 sql:'DROP TABLE dbTable'
  dropTable(dbTable) {
	  let _this = this
    return new Promise((resolve, reject) => {
      plus.sqlite.executeSql({
        name: this.dbName,
        sql: `DROP TABLE ${dbTable}`,
        success(e) {
          resolve(e);
        },
        fail(e) {
			_this.addlog('删除操作',e)
			_this.addlog('删除操作sql',sql)
          reject(e);
        }
      })
    })
  },

  // 向表格里添加数据 sql:'INSERT INTO dbTable VALUES('x','x','x')'   对应新增
  // 或者 sql:'INSERT INTO dbTable ('x','x','x') VALUES('x','x','x')'   具体新增
  // 插入 INSERT INTO  、 dbTable 是表名、根据表头列名插入列值
  insertTableData(dbTable, data, condition) {
    // 判断有没有传参
	let _this = this
    if (dbTable !== undefined && data !== undefined) {
      // 判断传的参是否有值
      var bol = (JSON.stringify(data) == "{}");
      if (!bol) {
        if (condition == undefined) {
          var sql = `INSERT INTO ${dbTable} VALUES(${data})`;
        } else {
          var sql = `INSERT INTO ${dbTable} (${condition}) VALUES(${data})`;
        }
        //console.log(sql);
        return new Promise((resolve, reject) => {
          // 表格添加数据
          plus.sqlite.executeSql({
            name: this.dbName,
            sql: sql,
            success(e) {
              resolve(e);
            },
            fail(e) {
				_this.addlog('新增操作',e)
				_this.addlog('新增操作sql',sql)
              reject(e);
            }
          })
        })
      } else {
        return new Promise((resolve, reject) => { reject("错误添加") })
      }
    } else {
      return new Promise((resolve, reject) => { reject("错误添加") })
    }
  },
  
  // 根据条件向表格里添加数据  有数据更新、无数据插入
  // (建表时需要设置主键) 例如 --- "roomid" varchar(50) PRIMARY KEY
  insertOrReplaceData(dbTable, data, condition) {
    // 判断有没有传参
    if (dbTable !== undefined && data !== undefined) {
        if (condition == undefined) {
          var sql = `INSERT OR REPLACE INTO ${dbTable} VALUES('${data}')`;
        } else {
          var sql = `INSERT OR REPLACE INTO ${dbTable} (${condition}) VALUES(${data})`;
        }
        // console.log(sql);
        return new Promise((resolve, reject) => {
          // 表格添加数据
          plus.sqlite.executeSql({
            name: this.dbName,
            sql: sql,
            success(e) {
              resolve(e);
            },
            fail(e) {
              reject(e);
            }
          })
      })
    } else {
      return new Promise((resolve, reject) => { reject("错误添加") })
    }
  },

  // 查询获取数据库里的数据 sql:'SELECT * FROM dbTable WHERE lname = 'lvalue''
  // 查询 SELECT * FROM 、 dbTable 是表名、 WHERE 查找条件 lname,lvalue 是查询条件的列名和列值
   selectTableData(dbTable, lname, lvalue, cc, dd) {
    if (dbTable !== undefined) {
      // 第一个是表单名称，后两个参数是列表名，用来检索
      if (lname !== undefined && cc !== undefined) {
        // 两个检索条件
        var sql = `SELECT * FROM ${dbTable} WHERE ${lname} = '${lvalue}' AND ${cc} = '${dd}'`;
      }
      if (lname !== undefined && cc == undefined) {
        // 一个检索条件
        var sql = `SELECT * FROM ${dbTable} WHERE ${lname} = '${lvalue}'`;
        // console.log(sql);
      }
      if (lname == undefined) {
        var sql = `SELECT * FROM ${dbTable}`;
      }
	  
	  if(this.myconfig==''){
		  //第一次初始化，这个缓存没被刷新，重新获取
		  this.myconfig = uni.getStorageSync('myconfig')
	  }
	  
	  if(this.user==''||this.user==null){
	  		//第一次初始化，这个缓存没被刷新，重新获取
	  		this.user = uni.getStorageSync('user')
	  }
	  let to_api_table = ['inventory_view','shelves','procure','warehouse','userlogin','user','outask','kc','checkVouch']
	  let condition = {}
	  //在线版，要调接口的表格，改写
	  if(to_api_table.includes(dbTable)&&this.myconfig.online){
		  if(lname !== undefined){
			  condition = {number:lvalue}//默认查编码
		  }
		  if(dbTable=='inventory_view'){
			  dbTable = 'inventory'
		  }
		  if(dbTable=='procure'){
		  	  condition = {
				  warehousing_code:lvalue,
				  uid:this.user.id
			  }
		  }
		  
		  let stock_id = this.default_stock_id
		  if(uni.getStorageSync('user')!=null){
		  		stock_id = uni.getStorageSync('user').stock_id
		  }
		  
		  if(dbTable=='warehouse'&&lname !== undefined){
		  	  condition = {id:lvalue}
		  }
		  
		  if(dbTable=='userlogin'&&lname !== undefined){
		  	  condition = {username:lvalue,password:dd}
		  }
		  
		  if(dbTable=='outask'){
		  	  condition = {material_code:lvalue}
		  }
		  
		  if(dbTable=='checkVouch'){
		  	  condition = {uuid:lvalue,warehouse_id:stock_id}
		  }
		  
		  if(dbTable=='shelves'){
		  	  condition.warehouse_id = stock_id
		  }
		  
		  if(dbTable=='kc'){
			condition = {keyword:lvalue,warehouse_id:stock_id}
			if (lname !== undefined ) {
				//condition.inv_number = lvalue
			}
			if (cc !== undefined && dd!='') {
				condition.cBatch = dd
			}
		  }
		  
		  //20231204在线版
		  let pageinfo = {
		  	table:dbTable,
		  	pagesize:99999,
		  	page:0,
		  	order_str:'',
		  	condition_str:JSON.stringify(condition)
		  }
		  
		  return new Promise((resolve, reject) => {
			 Api.getPageList(pageinfo).then(res=>{
				  //没翻页，直接返回数组
				  if(res.data.data == undefined){
					  resolve(res.data);
				  }else{
				  	  resolve(res.data.data);
				  }
			  }).catch(err=>{
				  console.log(err)
			  })
		  })
	  }
	  
	  //有可能，在线版，还读本地仓库表
		return new Promise((resolve, reject) => {
		  // 表格查询数据  执行查询的SQL语句
		  plus.sqlite.selectSql({
			name: this.dbName,
			sql: sql,
			success(e) {
			  resolve(e);
			},
			fail(e) {
			  reject(e);
			}
		  })
		})
    } else {
      return new Promise((resolve, reject) => { reject("错误查询") });
    }
  },

  // 删除表里的数据 sql:'DELETE FROM dbTable WHERE lname = 'lvalue''
  // 删除 DELETE FROM 、 dbTable 是表名、 WHERE 查找条件 lname,lvalue 是查询条件的列名和列值
  deleteTableData(dbTable, lname, lvalue, ww, ee) {
	  let _this = this
    if (dbTable !== undefined) {
      if (lname == undefined) {
        var sql = `DELETE FROM ${dbTable}`;
      } else {
        if (ww !== undefined) {
          // 两个检索条件
          var sql = `DELETE FROM ${dbTable} WHERE ${lname} = '${lvalue}' AND ${ww} = '${ee}'`;
        } else {
          // 一个检索条件
          var sql = `DELETE FROM ${dbTable} WHERE ${lname} = '${lvalue}'`;
        }
      }
	  let _this = this
	  //
      return new Promise((resolve, reject) => {
        // 删除表数据
        plus.sqlite.executeSql({
          name: this.dbName,
          sql: sql,
          success(e) {
			//_this.exeSQL("COMMIT;")
            resolve(e);
          },
          fail(e) {
			// _this.exeSQL("ROLLBACK;")
			_this.addlog('删除操作',e)
			_this.addlog('删除操作sql',sql)
            reject(e);
          }
        })
      })
    } else {
      return new Promise((resolve, reject) => { reject("错误删除") });
    }
  },

  // 修改数据表里的数据 sql:"UPDATE dbTable SET 列名 = '列值',列名 = '列值' WHERE lname = 'lvalue'"
  // 修改 UPDATE 、 dbTable 是表名, data: 要修改的列名=修改后列值, lname,lvalue 是查询条件的列名和列值
  updateTableData(dbTable, data, lname, lvalue) {
	  let _this = this
    if (lname == undefined) {
      var sql = `UPDATE ${dbTable} SET ${data}`;
    } else {
      var sql = `UPDATE ${dbTable} SET ${data} WHERE ${lname} = '${lvalue}'`;
    }
    // WHERE 前面是要修改的列名、列值，后面是条件的列名、列值
    return new Promise((resolve, reject) => {
      // 修改表数据
      plus.sqlite.executeSql({
        name: this.dbName,
        sql: sql,
        success(e) {
          resolve(e);
        },
        fail(e) {
			_this.addlog('更新操作',e)
			_this.addlog('更新操作sql',sql)
          reject(e);
        }
      })
    })
  },

  // 获取指定数据条数  sql:"SELECT * FROM dbTable ORDER BY 'id' DESC LIMIT 15 OFFSET 'num'"
  // dbTable 表名, ORDER BY 代表排序默认正序, id 是排序的条件 DESC 代表倒序，从最后一条数据开始拿
  // LIMIT 15 OFFSET '${num}',这句的意思是跳过 num 条拿 15 条数据, num 为跳过多少条数据是动态值
  // 例 初始num设为0，就从最后的数据开始拿15条，下次不拿刚获取的数据，所以可以让num为15，这样就能一步一步的拿完所有的数据
  pullSQL(dbTable, id, num) {
    return new Promise((resolve, reject) => {
      plus.sqlite.selectSql({
        name: this.dbName,
        sql: `SELECT * FROM ${dbTable} ORDER BY '${id}' DESC LIMIT 15 OFFSET '${num}'`,
        success(e) {
          resolve(e);
        },
        fail(e) {
          reject(e);
        }
      })
    })
  },
  
  //执行sql
  exeSQL(sql) {
	  let _this = this
    return new Promise((resolve, reject) => {
      plus.sqlite.executeSql({
        name: this.dbName,
        sql: sql,
        success(e) {
			//console.log(e)
          resolve(e);
        },
        fail(e) {
			console.log(e.message)
			_this.addlog('执行sql异常',e)
			_this.addlog('执行sql',sql)
          reject(e.message);
        }
      })
    })
  },
  selectSQL(sql) {
    return new Promise((resolve, reject) => {
      plus.sqlite.selectSql({
        name: this.dbName,
        sql: sql,
        success(e) {
          resolve(e);
        },
        fail(e) {
          reject(e);
        }
      })
    })
  },
  
  // 查询所有数据库表名
  queryDBTable(name) {
    return new Promise((resolve, reject) => {
      plus.sqlite.selectSql({
        name: name,
        sql: "select * FROM sqlite_master where type='table'",
        success(e) {
          resolve(e);
        },
        fail(e) {
          console.log(e)
          reject(e);
        }
      })
    })
  },
  
// 查询表、视图是否存在
 queryIsTable(tabName,type='table') {
  return new Promise((resolve, reject) => {
    plus.sqlite.selectSql({
      name: this.dbName,
      sql: `select count(*) as isTable FROM sqlite_master where type='${type}' and name='${tabName}'`,
      success(e) {
        resolve(e[0].isTable ? true : false);
      },
      fail(e) {
        reject(e);
      }
    })
  })
},
// 查询索引是否存在
 queryIsIndex(index_name) {
  return new Promise((resolve, reject) => {
    plus.sqlite.selectSql({
      name: this.dbName,
      sql: `select name FROM sqlite_master where type='index' and name='${index_name}'`,
      success(e) {
        resolve(e[0].name ? true : false);
      },
      fail(e) {
        reject(e);
      }
    })
  })
},

// 添加数据
 addSaveData(tabName, obj) {
  if (obj) {
    let keys = Object.keys(obj)
    let keyStr = keys.toString()
    let valStr = ''
	let _this = this
	
    keys.forEach((item, index) => {
      if (keys.length - 1 == index) {
        valStr += ('"' + obj[item] + '"')
      } else {
        valStr += ('"' + obj[item] + '",')
      }
    })
    // console.log(valStr)
    let sqlStr = `insert into ${tabName}(${keyStr}) values(${valStr})`
    return new Promise((resolve, reject) => {
      plus.sqlite.executeSql({
        name: this.dbName,
        sql: sqlStr,
        success(e) {
			 resolve(e);
        },
        fail(e) {
			//console.log(e)
			_this.addlog('新增操作',e)
			_this.addlog('新增操作sql',sqlStr) 
          reject(e);
        }
      })
    })
  } else {
    return new Promise((resolve, reject) => {
      reject("错误")
    })
  }
},
  // 查询数据库数据
  selectDataList( tabName, setData, byName, byType) {
    let setStr = ''
    let sql = ''
    if (JSON.stringify(setData) !== '{}') {
      let dataKeys = Object.keys(setData)
      dataKeys.forEach((item, index) => {
        setStr += (
          `${item}=${JSON.stringify(setData[item])}${dataKeys.length - 1 !== index ? " and " : ""}`)
      })
      sql = `select * from ${tabName} where ${setStr}`
    } else {
      sql = `select * from ${tabName}`
    }
    if (byName && byType) {
      // desc asc
      sql += ` order by ${byName} ${byType}`
    }
    
    if (tabName !== undefined) {
      return new Promise((resolve, reject) => {
        plus.sqlite.selectSql({
          name: this.dbName,
          sql: sql,
          success(e) {
            resolve(e);
          },
          fail(e) {
            console.log(e)
            reject(e);
          }
        })
      })
    } else {
      return new Promise((resolve, reject) => {
        reject("错误")
      });
    }
  },
  // 获取数据库分页数据
  /**
   * 
   * @param {*} name 
   * @param {*} tabName 
   * @param {*} num 页码
   * @param {*} size 页面大小返回条数
   * @param {*} byName 排序主键字段
   * @param {*} byType 排序类型 desc倒序 / asc正序
   */
  async queryDataList( tabName, num, size=15 ,where = ' 1=1 ', byName='', byType='') {
	  
    let count = 0
  	let sql = ''
  	let numindex = 0

  	await this.queryCount(tabName,where).then((resNum) => {
		if(resNum[0].num<=size){
			count = 1
		}else{
			count = Math.ceil(resNum[0].num / size)
		}
  	})
  	if(((num - 1) * size) == 0) {
  	    numindex = 0
  	} else {
  		numindex = ((num - 1) * size) + 1
  	}
	
  	sql = `select * from ${tabName} where ${where}`
  	if(byName && byType) {
  		// desc asc
  		sql += ` order by ${byName} ${byType}`
  	}
  	sql += ` limit ${numindex},${size}`
	
  	if (count < num - 1) {
  		return new Promise((resolve, reject) => {
  			reject("无数据")
  		});
  	} else {
  		return new Promise((resolve, reject) => {
  			plus.sqlite.selectSql({
  				name: this.dbName,
  				// sql: "select * from userInfo limit 3 offset 3",
  				sql:sql ,
  				success(e) {
  					resolve(e);
  				},
  				fail(e) {
  					reject(e);
  				}
  			})
  		})
  	}
  },
  // 查询表数据总条数
 queryCount(tabName,where = ' 1=1 ') {
  return new Promise((resolve, reject) => {
    plus.sqlite.selectSql({
			name: this.dbName,
			sql: "select count(*) as num from " + tabName + " where "+where,
			success(e) {
				resolve(e);
			},
			fail(e) {
				reject(e);
			}
		})
  })
},
// 修改（更新）数据
// 示例：UPDATE COMPANY SET ADDRESS = 'Texas' WHERE ID = 6;
// UPDATE 表名 SET 要修改字段 = '修改内容' WHERE 筛选条件 = 6;
/**
 * 
 * @param {*} name 数据库名
 * @param {*} tabName 表名
 * @param {*} setData 设置值 （修改字段 + 修改内容）
 * @param {*} setName 筛选条件
 * @param {*} setVal 筛选值
 * @returns 
 */
updateSqlData(tabName, setData, setName, setVal) {
	let _this = this
  if (JSON.stringify(setData) !== '{}') {
    let dataKeys = Object.keys(setData)
		let setStr = ''
		dataKeys.forEach((item, index) => {
      // console.log(item, setData[item])
			setStr += (
				`${item} = ${JSON.stringify(setData[item])}${dataKeys.length - 1 !== index ? "," : ""}`)
    })
	let sqlStr = `update ${tabName} set ${setStr} where ${setName} = "${setVal}"`
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: sqlStr,
				success(e) {
					resolve(e);
				},
				fail(e) {
					_this.addlog('新增操作',e)
					_this.addlog('新增操作sql',sqlStr)
					reject(e);
				}
			})
		})
	} else {
		return new Promise((resolve, reject) => {
			reject("错误")
		});
	}
},
/* 
获取编码，输入日期+标识，返回编码 
 */
setMcode(date,type,next_number_max_str = ''){
	if(date==''||date==undefined){
		return promise.reject('新增单号失败')
	}
	date = date.substr(2) //截取，从第2位开始 230828
	
	var sql = 'select * from mcode where date="'+date+'" and type="'+type+'" order by number desc limit 1';
	let _this = this
	let isql = ''
	
	return new Promise((resolve, reject) => {
	plus.sqlite.selectSql({
			name: this.dbName,
			sql: sql,
			success(res) {
				let number = '';
				let next_number = 1;
				
				if(res.length==0){
					next_number = '1001';
				}else{
					next_number = res[0].number+1
				}
				
				//服务器返回的单号最大值,在点击同步的时候，更新
				if(next_number_max_str!=''){
					//console.log('最大',next_number_max_str)
					next_number = Number(next_number_max_str)
					next_number = 1000+next_number;
				}
				
				number = next_number.toString().slice(1);
				
				let code = type+date+number;
				isql = '"'+date+'","'+type+'","'+next_number+'","'+code+'"'
				_this.insertTableData('mcode',isql);
				resolve(code)
			},
			fail(e) {
				_this.addlog('设置单号失败',e)
				_this.addlog('设置单号sql',isql)
				reject(e);
			}
		})
	})
},
//获取出入库本机编码
getMcode(date,type){
	if(date==''||date==undefined){
		return promise.reject('获取单号失败')
	}
	
	let _this = this;
	date = date.substr(2) //截取，从第2位开始 230828
	var sql = 'select * from mcode where date="'+date+'" and type="'+type+'" order by number desc limit 1';
	return new Promise((resolve, reject) => {
	  plus.sqlite.selectSql({
	  		name: this.dbName,
	  		sql: sql,
	  		success(res) {
				resolve(res)
	  		},
	  		fail(e) {
				_this.addlog('获取单号失败',e)
				_this.addlog('获取单号sql',sql)
	  			reject(e);
	  		}
	  	})
	})
},
//首页同步数据
async synBaseData(fname){
	let data = ''
	let delflag = false
	
	//物料不在这里删除表，在清空数据那
	let no_delete_table = ['inventory','procure','appmaterial']
	let cover_flag = ['inventory','procure','appmaterial']
	if(!no_delete_table.includes(fname)){
		delflag = true
	}else{
		//3个例外的表，如果同步模式是覆盖，则删除
		if(fname == 'inventory'&&this.myconfig.inv_cover==1){
			delflag = true
		}
		if(fname == 'procure'&&this.myconfig.procure_cover==1){
			delflag = true
		}
		
		if(fname == 'appmaterial'&&this.myconfig.material_cover==1){
			delflag = true
		}
	}
	
	if(delflag){
		await this.queryIsTable(fname).then(res => {
			this.dropTable(fname)
		})
	}
	
	//新建表appmaterial
	if(fname == 'appmaterial'){//领料申请单
		data = '"id" INTEGER PRIMARY KEY,"auto_id" TEXT,"row_id" INTEGER,"pcode" TEXT,"pdate" TEXT,"cdepcode" TEXT,"cdepname" TEXT,"quantity" REAL(18,4),"commit_quantity" REAL(18,4),"warehouse_id" INTEGER,"warehouse_code" TEXT,"warehouse_name" TEXT,"tj_shelves_id" INTEGER,"tj_shelves_name" TEXT,"inv_number" TEXT,"inv_name" TEXT,"inv_specification" TEXT,"inv_attributes" TEXT,"unit_code" TEXT,"unit_name" TEXT,"source" TEXT,"fitemssname" TEXT,"remark" TEXT,"cUser_Id" TEXT,"cUser_Name" TEXT,"fclose" INTEGER DEFAULT 0';
	}
	if(fname == 'procure'){//采购订单
		data = '"id" INTEGER PRIMARY KEY,"auto_id"  TEXT,"row_id"  INTEGER,"pcode"  TEXT,"pdate"  TEXT,"factory_code"  TEXT,"factory_name"  TEXT,"quantity"  REAL(18,4),"commit_quantity"  REAL(18,4),"no_quantity"  REAL(18,4),"warehouse_id"  INTEGER,"warehouse_name"  TEXT,"shelves_id"  INTEGER,"shelves_name"  TEXT,"lastest_warehouse_id"  INTEGER,"lastest_warehouse_name"  TEXT,"lastest_shelves_id"  INTEGER,"lastest_shelves_name"  TEXT,"inv_number"  TEXT,"inv_name"  TEXT,"inv_specification"  TEXT,"inv_attributes"  TEXT,"unit_code"  TEXT,"unit_name"  TEXT,"remark" TEXT,"fclose"  INTEGER';
	}
	if(fname == 'inventory'){//物料档案
		data = '"id" INTEGER,"number" TEXT,"name" TEXT,"specification" TEXT,"unit_code" TEXT,"unit" TEXT,"warehouse_id" TEXT,"tj_shelves_id" TEXT,"tj_shelves_name" TEXT,"classification_id" TEXT,"mbatch" INTEGER,"safe_num" REAL(18,4),"max_num" REAL(18,4),"min_num" REAL(18,4),"ifshangjia" INTEGER,"ifjianhuo" INTEGER,"remark" TEXT,PRIMARY KEY ("number")'
	}
	if(fname == 'kc'){//即时库存
		data = '"kc_id" INTEGER,"AutoID" INTEGER,"cInvCode" TEXT,"cBatch" TEXT,"name" TEXT,"specification" TEXT,"cFree1" TEXT,"unit" TEXT,"unit_code" TEXT,"iQuantity" REAL(18,4),"curiQuantity" REAL(18,4),"cWhCode" TEXT,"warehouse_id" INTEGER,"warehouse_name" TEXT,"shelves_id" INTEGER,"shelves_code" TEXT,"shelves_name" TEXT,"shelves_type" INTEGER,"classification_id" TEXT,"classification_name" TEXT';
	}
	if(fname == 'warehouse'){//即时库存
		data = '"id" INTEGER,"name" TEXT,"number" TEXT,"remark" TEXT';	
	}
	if(fname == 'shelves'){//货架
		data = '"id" INTEGER,"number"  TEXT,"name"  TEXT,"warehouse_id"  INTEGER,"type"  INTEGER,"remark"  TEXT,"row_number"  INTEGER,"column_number"  INTEGER,"layers_number"  INTEGER,"max_number"  TEXT,"max_weight"  TEXT,"max_volume"  TEXT,"long"  REAL,"width"  REAL,"height"  REAL,"size"  TEXT,"picking_ordre"  TEXT,"listing_order"  TEXT,"ifempty" INTEGER DEFAULT 1';	
	}
	if(fname == 'shelvesInvclass'){//货架和物料分类的关系策略表
		data = '"shelves_id" INTEGER,"inv_class_id"  INTEGER,"classification_id" TEXT';	
	}
	if(fname == 'invShelvesLastest'){//货架和物料 最新路径关系表
		data = '"inv_id" INTEGER,"warehouse_id" INTEGER,"shelves_id" INTEGER';	
	}
	
	//不存在则创建
	let table_exist = false
	await this.queryIsTable(fname).then(texist=>{
		table_exist = texist
		if(texist){
			//货架、库区索引
			this.exeSQL("DROP INDEX shelves_index_name_number;")
			this.exeSQL("CREATE INDEX shelves_index_name_number on shelves (name, number);")
			
			//库存
			this.exeSQL("DROP INDEX kc_index_number;")
			this.exeSQL("CREATE INDEX kc_index_number on kc (cInvCode , shelves_code)");
			
			//货架、物料分类策略
			this.exeSQL("DROP INDEX shelves_inc_class_index;")
			this.exeSQL("CREATE INDEX shelves_inc_class_index ON shelvesInvclass (shelves_id ASC)")
			this.exeSQL("DROP INDEX shelves_inc_class_index2;")
			this.exeSQL("CREATE INDEX shelves_inc_class_index2 ON shelvesInvclass (shelves_id ASC, classification_id ASC)")
		}
	})
	
	if(!table_exist){
		await this.createTable(fname,data).catch(err=>{
			console.log(err)
		})
	}
	
	if(fname == 'inventory'){
		//物料档案索引
		//this.exeSQL("DROP INDEX inventory_index_nns;")
		//this.exeSQL("DROP INDEX inventory_index_number;")
		this.exeSQL("CREATE INDEX inventory_index_nns on inventory (name, number, specification)");
		this.exeSQL("CREATE INDEX inventory_index_number on inventory (number)");
		this.queryIsTable('inventory_view','view').then(res => {
			if(!res){
				this.exeSQL('CREATE VIEW "inventory_view" AS SELECT inv.*,isl.warehouse_id lastest_warehouse_id,isl.shelves_id lastest_shelves_id,(SELECT name from shelves sh where sh.id=isl.shelves_id) lastest_shelves_name,(SELECT name from warehouse wh where wh.id=isl.warehouse_id) lastest_warehouse_name from inventory inv  LEFT JOIN invShelvesLastest isl on isl.inv_id=inv.id')
			}
		})
	}
},
//创建本地pda相关表,清除单据时执行（清空表结构、同时创建表）
async createPdaTable(dropflag){
	if(dropflag){
		//清空本地单据相关表
		this.dropTable('stockbill');
		this.dropTable('stockbillentry');
		
		this.dropTable('check_kc');
		this.dropTable('check_kc_item');
		
		this.dropTable('allot');
		this.queryIsTable('allot_view','view').then(res => {
			if(res){
				this.exeSQL("DROP VIEW allot_view;")
			}
		})
		
		this.dropTable('allot_item');
		//this.dropTable('action_log');//删除后，回到首页会传送日志到服务器，导致找不到表格
		//this.dropTable('user');
		//创建物料、最近货架关系视图
		this.queryIsTable('inventory_view','view').then(res => {
			if(res){
				this.exeSQL("DROP VIEW inventory_view;")
			}
		})
		this.queryIsTable('check_kc_item_view','view').then(res => {
			if(res){
				this.exeSQL("DROP VIEW check_kc_item_view;")
			}
		})
		console.log('delete table')
	}
	
	//创建本地单据表头
	await this.queryIsTable('stockbill').then(res => {
		if(!res){
			//单据表
			const data = '"id"  INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"auto_id"  TEXT,"source_code"  TEXT,"order_type"  INTEGER,"FBillNo"  TEXT,"FDate"  TEXT,"a_remark"  TEXT,"stock_id"  INTEGER,"to_stock_id"  INTEGER DEFAULT 0,"to_shelves_id"  INTEGER,"to_shelves_name"  TEXT,"status"  INTEGER,"syn_status"  INTEGER DEFAULT 0,"total_qty"  REAL(18,4),"factory_code"  TEXT,"factory_name"  TEXT,"userid"  TEXT,"create_date"  TEXT,"rd_name" TEXT';
			this.createTable('stockbill',data)
			console.log('create stockbill ok')
		}
	});
	//本地单据明细
	await this.queryIsTable('stockbillentry').then(res => {
		if(!res){
			const data = '"id"  INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"FBillNo"  TEXT,"auto_id"  TEXT,"row_id"  INTEGER,"local_row_id" INTEGER,"inv_number"  TEXT,"inv_name"  TEXT,"inv_specification"  TEXT,"inv_attributes"  TEXT,"inv_unit"  TEXT,"inv_unit_code" TEXT,"store_unit"  TEXT,"store_unit_code" TEXT,"fqty"  REAL(18,4),"fauxqty"  REAL(18,4),"cBatch" TEXT,"shelves_id"  INTEGER,"shelves_type"  INTEGER,"shelves_name"  TEXT,"b_remark"  TEXT,"status"  INTEGER DEFAULT 1'; 
			this.createTable('stockbillentry',data)
			//this.exeSQL("CREATE VIEW stockbill_view AS SELECT a.*, b.FName,b.FNumber,b.FModel,b.FUnit_Name,b.FStock_Name,b.FNetWeight,b.FUnitID FROM stockbillentry AS a LEFT JOIN material AS b ON a.FItemID = b.FItemID")
			console.log('stockbillentry ok')
		}
	});
	
	//盘点表头
	await this.queryIsTable('check_kc').then(res => {
		if(!res){
			//type 1全盘，2物料编码区间 3货架库区 4物料分类
			const data = '"id"  INTEGER PRIMARY KEY,"FBillNo"  TEXT(50) NOT NULL,"FDate"  TEXT(20),"bookDate"  TEXT(20),"type"  INTEGER DEFAULT 1,"stock_id"  INTEGER,"invStart"  TEXT(20),"invEnd"  TEXT(20),"shelves_des"  TEXT,"inv_class_name"  TEXT,"rowStart"  INTEGER,"rowEnd"  INTEGER,"totalnum"  REAL(10,4),"status"  INTEGER DEFAULT 0,"syn_status"  INTEGER DEFAULT 0,"userid"  TEXT,"create_date"  TEXT,"remark"  TEXT'
			this.createTable('check_kc',data)
			console.log('create check_kc ok')
		}
	});
	//盘点表体
	await this.queryIsTable('check_kc_item').then(res => {
		if(!res){
			const data = '"id"  INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"FBillNo"  TEXT(50),"inv_id"  INTEGER,"inv_number"  TEXT(50),"inv_name"  TEXT(100),"inv_specification"  TEXT(50),"inv_attributes"  TEXT(50),"inv_unit" TEXT,"inv_unit_code" TEXT,"store_unit" TEXT,"store_unit_code" TEXT,"shelves_id"  INTEGER,"shelves_name"  TEXT(50),"cBatch"  TEXT(50),"kc_qty"  REAL(18,4),"kc_auxqty"  REAL(18,4),"check_qty"  REAL(18,4),"check_auxqty"  REAL(18,4),"isnew"  INTEGER DEFAULT 0,"scan_flag" INTEGER DEFAULT 0,"scan_datetime" TEXT'
			this.createTable('check_kc_item',data)
			
			this.exeSQL("CREATE VIEW check_kc_item_view AS select a.id,a.FBillNo,a.inv_id,a.inv_number,a.shelves_id,a.shelves_name,a.kc_qty,a.check_qty,a.isnew,a.scan_flag,a.scan_datetime,b.name inv_name,ifnull(b.specification,'') inv_specification,b.unit inv_unit,b.unit_code inv_unit_code,ifnull(b.cBatch,'') cBatch from check_kc_item a LEFT JOIN inventory b on b.number=a.inv_number order by a.scan_flag,a.inv_number")
			console.log('check_kc_item_view ok')
		}
	});
	
	//调拨表头
	await this.queryIsTable('allot').then(res => {
		if(!res){
			//type 1全盘，2物料编码区间
			const data = '"id"  INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"FBillNo"  TEXT(50) NOT NULL,"FDate"  TEXT(20),"type"  INTEGER DEFAULT 1,"stock_id"  INTEGER,"to_stock_id"  INTEGER,"to_shelves_id" TEXT,"to_shelves_name" TEXT,"invStart"  TEXT(20),"invEnd"  TEXT(20),"rowStart"  INTEGER,"rowEnd"  INTEGER,"totalnum"  REAL(10,4),"status"  INTEGER DEFAULT 1,"syn_status"  INTEGER DEFAULT 0,"userid"  TEXT,"create_date" TEXT,"remark"  TEXT'
			this.createTable('allot',data)
			
			this.exeSQL('CREATE VIEW "allot_view" AS SELECT a.*,b.name stock_name,c.name to_stock_name FROM allot a INNER JOIN warehouse b ON b.id = a.stock_id INNER JOIN warehouse c ON c.id = a.to_stock_id')
			console.log('allot ok')
		}
	});
	//调拨表体
	await this.queryIsTable('allot_item').then(res => {
		if(!res){
			const data = '"id"  INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"kc_id"  INTEGER,"FBillNo"  TEXT(50),"inv_id"  INTEGER,"inv_number"  TEXT(50),"inv_name"  TEXT(100),"inv_specification"  TEXT(50),"inv_attributes"  TEXT(50),"inv_unit" TEXT,"inv_unit_code" TEXT,"store_unit" TEXT,"store_unit_code" TEXT,"shelves_id"  INTEGER,"to_shelves_id"  INTEGER,"shelves_name"  TEXT(50),"to_shelves_name"  TEXT(50),"cBatch"  TEXT(50),"kc_qty"  REAL(18,4),"kc_auxqty"  REAL(18,4),"allot_qty"  REAL(18,4),"allot_auxqty"  REAL(18,4)'
			this.createTable('allot_item',data)
			console.log('allot_item ok')
		}
	});
	//创建删除视图
	//this.exeSQL("CREATE VIEW stockbillentry_view AS SELECT a.*, b.FName,b.FNumber,b.FModel,b.FUnit_Name,b.FStock_Name,b.FNetWeight FROM stockbillentry AS a LEFT JOIN material AS b ON a.FItemID = b.FItemID");
},
//清空单据、物料档案
async clearData(del_table_flag = false){
	
	if(!this.myconfig.online){
		//模式，覆盖才清空    离线才清空档案
		if(this.myconfig.inv_cover){
			this.deleteTableData('inventory').catch(err=>{
				throw(err)
			})
		}else{
			console.log('不删物料记录')
		}
		
		if(this.myconfig.procure_cover){
			this.deleteTableData('procure').catch(err=>{
				throw(err)
			}) //清空采购订单
		}
		
		if(this.myconfig.material_cover){
			this.deleteTableData('appmaterial').catch(err=>{
				throw(err)
			}) //清空领料单
		}
		
		//货架
		this.deleteTableData('shelves').catch(err=>{
			throw(err)
		})
	}
	
	this.deleteTableData('stockbill').catch(err=>{
		throw(err)
	})
	this.deleteTableData('stockbillentry').catch(err=>{
		throw(err)
	})

	//盘点，表头
	this.deleteTableData('check_kc').catch(err=>{
		throw(err)
	})
	//盘点，表体
	this.deleteTableData('check_kc_item').catch(err=>{
		throw(err)
	})
	
	//调拨，表头
	this.deleteTableData('allot').catch(err=>{
		throw(err)
	})
	//调拨，表体
	this.deleteTableData('allot_item').catch(err=>{
		throw(err)
	})
	//日志
	this.deleteTableData('action_log').catch(err=>{
		throw(err)
	})
	
	//删除表结构、同时重新创建
	if(del_table_flag){
		this.createPdaTable(del_table_flag).catch(err=>{
			throw(err)
		})
	}
},
/* 
 插入同步数据
 */
async addAsyncData(filename){
	if(filename==''||filename==undefined){
		throw('同步数据表名为空')
	}
	let _this = this
	let user = uni.getStorageSync('user');
	let no_delete_table = ['inventory','procure','appmaterial']//有2种同步模式表
	let cover_arr = {
		//0增量，1新增
		'inventory':this.myconfig.inv_cover,
		'procure':this.myconfig.procure_cover,
		'appmaterial':this.myconfig.material_cover
	}
	let fname = filename //物料名有分inventory1,2,3
	if(filename.indexOf('inventory')!=-1){
		fname = 'inventory'
	}
	
	//有2种模式，增量和覆盖
	if(no_delete_table.includes(fname)){
		let last_id = 0
		if(cover_arr[fname] == undefined){
			throw(fname+'同步标识没有保存设置')
		}
		
		if(!cover_arr[fname]){
			//增量
			await this.selectSQL("select id from "+fname+" order by id desc limit 1").then(e => {
				let res = JSON.stringify(e)
				if ( res !== "[]") {
					//取最后1条记录
					last_id = e[0].id
				}
			}).catch(err=>{
				console.log(err)
				throw(err.message)
			})
		}
		
		await Api.getJsonContent(filename).then(res => {
			let rows = JSON.parse(res);//总数组
			let last_arr = rows.slice(0,1)//取第1个数组,json是按id倒序
			//let last_arr = rows[0]//取第1个数组,json是按id倒序
			if(last_arr.length==0){
				//throw('同步'+filename+'失败,空数据文件')
				this.addlog('同步数据','同步'+filename+'失败,空数据文件')
			}
			
			if(last_arr.length>0){
				if(cover_arr[fname] ||(!cover_arr[fname]&&last_arr[0].id>last_id)){
					console.log(cover_arr[fname]?'新增':'增量',fname+'开始处理')
					for(let m of rows){
						let sql = ''
						let specification = ''
						if(cover_arr[fname]||(!cover_arr[fname]&&m.id>last_id)){
							if(fname == 'appmaterial'){
								specification = Func.rpXiegan(m.inv_specification)//去掉反斜杆
							}else{
								specification = Func.rpXiegan(m.specification)//去掉反斜杆
							}
							if(fname == 'inventory'){
								sql = '"'+m.id+'","'+m.number+'","'+m.name+'","'+specification+'","'+m.unit_code+'","'+m.unit+'","'+m.warehouse_id+'","'+m.shelves_id+'","'+m.shelves_name+'","'+m.classification_id+'","'+m.mbatch+'","'+m.safe_num+'","'+m.max_num+'","'+m.min_num+'","'+m.ifshangjia+'","'+m.ifjianhuo+'",""';
							}
							if(fname == 'procure'){
								sql = '"'+m.id+'","'+m.auto_id+'","'+m.row_id+'","'+m.warehousing_code+'","'+m.warehousing_date+'","'+m.factory_code+'","'+m.factory_name+'","'+m.quantity+'","'+m.warehousing_quantity+'","'+m.no_quantity+'","'+m.warehouse_id+'","'+m.warehouse_name+'","'+m.shelves_id+'","'+m.shelves_name+'","'+m.lastest_warehouse_id+'","'+m.lastest_warehouse_name+'","'+m.lastest_shelves_id+'","'+m.lastest_shelves_name+'","'+m.inventory_number+'","'+m.name+'","'+specification+'","'+m.attributes+'","'+m.unit_code+'","'+m.unit+'","'+m.remark+'",0';
							}
							if(fname == 'appmaterial'){
								sql = '"'+m.id+'","'+m.auto_id+'","'+m.row_id+'","'+m.pcode+'","'+m.pdate+'","'+m.cdepcode+'","'+m.cdepname+'","'+m.quantity+'","'+m.commit_quantity+'","'+m.warehouse_id+'","'+m.warehouse_code+'","'+m.warehouse_name+'","'+m.tj_shelves_id+'","'+m.tj_shelves_name+'","'+m.inv_number+'","'+m.inv_name+'","'+specification+'","'+m.inv_attributes+'","'+m.unit_code+'","'+m.unit_name+'","'+m.source+'","'+m.fitemssname+'","'+m.remark+'","'+m.cUser_Id+'","'+m.cUser_Name+'",0';
							}
							
							this.insertTableData(fname,sql).catch(err=>{
								console.log(fname+"插入异常",err)
								console.log(sql)
								this.addlog('同步数据表'+fname,err)
								this.addlog('sql同步数据表'+fname,sql)
								throw(err.message)
							})
						}
					 }
					 console.log('json_last_id:'+filename,last_arr[0].id,'db-last_id:'+last_id)
				 }else{
					 console.log(filename+'不用处理')
				 }
			}
			 console.log(filename+' insert ok')
			 uni.$emit('indexAddInsertNum','ok')//通知首页下载的文件插入完成
		}); 
	}else{
		//kc,warehouse procure
		await Api.getJsonContent(filename).then(res => {
			 let arr = JSON.parse(res);//总数组
			 arr.forEach((m) => {
				 let sql = ''
				if(filename == 'kc'){
					if(user.stock_code == m.warehouse_number){
						//和登录选中的同个仓租才插入
						let specification = Func.rpXiegan(m.inv_specification)//去掉反斜杆
						sql = '"'+m.id+'","","'+m.inv_number+'","'+m.cBatch+'","'+m.inv_name+'","'+specification+'","","'+m.inv_unit+'","'+m.inv_unit_code+'","'+m.quantity+'","'+m.cur_quantity+'","'+m.warehouse_number+'","'+m.warehouse_id+'","'+m.warehouse_name+'","'+m.shelves_id+'","'+m.shelves_number+'","'+m.shelves_name+'","'+m.shelves_type+'","'+m.classification_id+'","'+m.classification_name+'"';		 
					}
				}
				if(filename == 'warehouse'){
					sql = '"'+m.id+'","'+m.name+'","'+m.number+'",""';
				}
				
				if(filename == 'shelves'){
					sql = '"'+m.id+'","'+m.number+'","'+m.name+'","'+m.warehouse_id+'","'+m.type+'","'+m.remark+'","'+m.row_number+'","'+m.column_number+'","'+m.layers_number+'","'+m.max_number+'","'+m.max_weight+'","'+m.max_volume+'","'+m.long+'","'+m.width+'","'+m.height+'","'+m.size+'","'+m.picking_ordre+'","'+m.listing_order+'","'+m.ifempty+'"';
				}
				
				if(fname == 'shelvesInvclass'){
					sql = '"'+m.shelves_id+'","'+m.inv_class_id+'","'+m.classification_id+'"';
				}
				
				if(fname == 'invShelvesLastest'){
					sql = '"'+m.inv_id+'","'+m.warehouse_id+'","'+m.shelves_id+'"';
				}
				
				if(sql!=''){
					this.insertTableData(filename,sql).catch(err=>{
						console.log("插入异常",err)
						this.addlog('同步数据',err)
						throw(err)
					})
				}
			 });
			 console.log(filename+' insert ok')
			 uni.$emit('indexAddInsertNum','ok')
		})
	}
},
//同步盘点任务
async addAsyncCheckData(){
	return new Promise(async(resolve, reject) => {
		let checkVouchs = []
		let uuid = uni.getStorageSync('uuid')
		let user = uni.getStorageSync('user')
		
		if(this.myconfig.online){
			//在线
			await this.selectTableData('checkVouch','uuid',uuid).then(res=>{
				checkVouchs = res;
			})
		}else{
			await Api.getJsonContent('checkVouch').then(res => {
				 checkVouchs = JSON.parse(res);//总数组
			})
		}
		
		if(checkVouchs['main']==undefined||!checkVouchs['main'].length){
			return reject('暂无盘点任务','error')
		}
		
		let insertNum = 0
		for(let checkVouch of checkVouchs['main']){
			 // if(checkVouch.pda!=''&&!checkVouch.pda.includes(uuid)){
				//  //pda标识不为空，同时不属于本机的盘点记录，则跳过 
				//  continue
			 // }
			 
			 let insert = true
			 await this.selectTableData('check_kc','id',checkVouch.id).then(res=>{
				if(res.length){
					//console.log(res)
					//本机已下载的，则跳过
					insert = false
				}
			 })
			 
			 //没下载过，同时表体不为空的，则操作(有可能表体)
			 let details = checkVouchs['detail'][checkVouch.code]
			 if(insert&&details!=undefined){
				 insertNum++
				 let main  = {
					 'id':checkVouch.id,
					 'FBillNo':checkVouch.code,
					 'FDate':checkVouch.code_date,
					 'bookDate':checkVouch.book_date,
					 'type':checkVouch.type,
					 'stock_id':checkVouch.warehouse_id,
					 'invStart':checkVouch.inv_number_start,
					 'invEnd':checkVouch.inv_number_end,
					 'shelves_des':checkVouch.shelves_des,
					 'inv_class_name':checkVouch.inv_class_name,
					 'totalnum':details.length,
					 'userid':user.userid,
					 'remark':checkVouch.remark
				 }
				 
				 await this.exeSQL('BEGIN;')
				 await this.addSaveData('check_kc',main).catch(error=>{
				 	this.exeSQL("ROLLBACK;")
				 	return reject(error.message)
				 })
				
				 //插入表体
				 for(let detail of details){
					await this.addSaveData('check_kc_item',{
						 'id':detail.id,
						 'FBillNo':checkVouch.code,
						 'inv_id':detail.inv_id,
						 'inv_name':detail.inv_name,
						 'inv_number':detail.inv_number,
						 'inv_specification':detail.specification,
						 'shelves_id':detail.shelves_id,
						 'shelves_name':detail.shelves_name,
						 'kc_qty':detail.kc_qty,
						 'check_qty':detail.check_qty,
						 'kc_auxqty':detail.kc_auxqty,
						 'check_auxqty':detail.check_auxqty,
						 'cBatch':detail.cBatch,
						 'isnew':detail.isnew,
						 'scan_flag':detail.scan_flag,
						 'inv_unit':detail.unit,
						 'inv_unit_code':detail.unit_code,
						 'store_unit':detail.store_unit,
						 'store_unit_code':detail.store_unit_code,
						 'scan_datetime':detail.scantime
					 }).catch(error=>{
					 	this.exeSQL("ROLLBACK;")
					 	return reject(error.message)
					 })
				 }
			 }
		}
		
		if(insertNum){
			this.exeSQL('COMMIT;')
			uni.$emit('insertCKKC')
			uni.hideLoading()
			return resolve(123)
		}else{
			return reject('暂无盘点任务','error')
		}
	});
},
//登录
async toLogin(username,password,stock_id){
	if(username==''||password==''){
		throw Error('参数错误')
	}
	
	let flag = false
	let stock_name = ''
	let stock_code = ''
	await this.selectTableData('warehouse','id',stock_id).then(res=>{
		if(!res.length){
			throw Error('不存在仓库'+stock_id+',请核实')
		}
		stock_name = res[0].name
		stock_code = res[0].number
	})
	let table = 'user'
	if(this.myconfig.online){
		table = 'userlogin'
	}
	await this.selectTableData(table,'username',username,'password',password).then(res=>{
		if(res.code === 1){
			res = res.msg
		}
		
		if(res.length>0){
			res[0].stock_id = stock_id
			res[0].stock_name = stock_name
			res[0].stock_code = stock_code
			uni.setStorageSync('user',res[0])
			uni.setStorageSync('username',username)
			flag = true
		}
	}).catch(errr=>{
		flag = false
	})
	uni.$emit("loginRes", {
		result:flag
	}) 
},
//获得即时库存,也可获取某货架、库区库存 、批号
getKc(inv_number,stock_id,shelves_id_or_code = '',batch = ''){
	if(inv_number==''||stock_id==0||stock_id==''){
		throw('获得即时库存参数错误')
	}
	let condition = {
		'inv_number':inv_number,
		'warehouse_id':stock_id
	}
	let sql = "select COALESCE(sum(iQuantity), 0) fqty,COALESCE(kc_id,0) kc_id from kc where cInvCode='"+inv_number+"' and warehouse_id='"+stock_id+"'"
	//有指定货架、库区
	if(isNaN(shelves_id_or_code)&&shelves_id_or_code!=''){
		sql += " and shelves_code = '"+shelves_id_or_code+"' "
		condition.shelves_number = shelves_id_or_code
	}else{
		if(shelves_id_or_code>0){
			sql += " and shelves_id = "+shelves_id_or_code
			condition.shelves_id = shelves_id_or_code
		}
	}
	//增加批号
	if(batch!=''){
		sql += " and cBatch = '"+batch+"'"
		condition.cBatch = batch
	}
	
	return new Promise((resolve, reject) => {
		if(!this.myconfig.online){
		  // 表格查询数据  执行查询的SQL语句
		  plus.sqlite.selectSql({
			name: this.dbName,
			sql: sql,
			success(e) {
			  resolve(e);
			},
			fail(el) {
			  reject(el);
			}
		  })
		}else{
			//20231204在线版
			let pageinfo = {
				table:'kc',
				pagesize:0,
				page:0,
				order_str:'cBatch asc',
				condition_str:JSON.stringify(condition)
			}
			
			Api.getPageList(pageinfo).then(res=>{
				resolve(res.data.data);
			}).catch(err=>{
				reject(err);
			})
			//
		}
	})
},
//添加单据
//单据类型，表头，表体，源单
//0收货，1上架，2拣货，3出库，4其他出库
//表头，表体
async addOrder(type,bill,billentry){
	if(JSON.stringify(bill) == '{}'){
		throw('表头参数异常')
	}
	if(JSON.stringify(billentry) == '{}'){
		throw('表体参数异常')
	}
	
	await this.selectTableData('stockbill','FBillNo',bill.FBillNo).then(res=>{
		if(res.length>0){
			throw('已存在单号,请在列表同步')
		}
	})

	//插入表头
	let _this = this
	let title = Func.getOrderTypeName(type)
	
	//this.exeSQL("BEGIN;")
	try{
		if(type==0){//收货、 入库
			//更新采购订单，未收、已收数量
			if(!this.myconfig.online){
				await this.dealProcureBillData(bill.source_code,billentry,'+')
			}
		}else if(type==1||type==3){//上架、领料出库
			//更新本地收货、拣货记录
			if(!this.myconfig.online){
				await this.dealStockBillData(bill.source_code,billentry,type,'+')
			}
		}else if(type==2){//领料
			//更新领料订单、已拣货数量
			if(!this.myconfig.online){
				await this.dealAppmaterialBillData(bill.source_code,billentry,'+')
			}
		}else if(type==11||type == 15||type == 17){
			//判断上架策略(其他入库、领料退回、直接上架)
			if(!this.myconfig.online){
				await this.checkShangjiaJianhuo(billentry,'shangjia')
			}
			if(type == 17){
				//直接上架库存记录，原库存记录没有货架、库区
				if(!this.myconfig.online){
					await this.checkMergeKcSum(billentry)
				}
			}
		}
	}catch(error){
		//this.exeSQL("ROLLBACK;")
		throw(error)
	}
	
	//插入表头
	await this.addSaveData('stockbill',bill)
	.catch(error=>{
		//this.exeSQL("ROLLBACK;")
		throw(error.message)
	})
	//插入表体
	await billentry.forEach((citem) => { 
		this.addSaveData('stockbillentry',citem).catch(error=>{
			//this.exeSQL("ROLLBACK;")
			throw(error.message)
		})
	});
	
	//在线版，自动回传
	if(this.myconfig.online){
		return new Promise(async(resolve, reject) => {
			//this.backSynAllData(this.user)
			this.backSynData('stockbill',bill,type) //单个回传
			.then(res=>{
				resolve(true)
			})
			.catch(err=>{
				reject(err)
			})
		})
	}else{
		return Promise.reject(true)
	}
},
/* 
 type=1新增、删除 上架记录时，更新收货记录状态，收货表体数量billentry fauxqty
 type=3新增、删除 领料出库记录是，更新拣货记录状态，拣货表体数量 billentry fauxqty
 因为都是操作本地单据的表，所以统一一个函数
 new_billentry 删除时，是本次单据编码（上架记录）
 */
async dealStockBillData(FBillNoPda,new_billentry,type,flag = '+'){
	let FBillNo = '' 
	let dealFlag = false
	let _this = this
	let title = ''
	if(type == 1){
		title = '上架'
	}else if(type == 3){
		title = '领料'
	}
	
	if(flag == '-'){
		await this.selectTableData('stockbillentry','FBillNo ',new_billentry).then(new_billentrys=>{ 
			FBillNo = new_billentry
			new_billentry = new_billentrys //上架、领料出库记录
		})
	}
	
	if(!new_billentry.length){
		throw('找不到表体记录')
	}
	
	if(type == 1){
		//判断上架策略
		await this.checkShangjiaJianhuo(new_billentry,'shangjia').catch(err=>{
			return Promise.reject(err) 
		})
	}
	
	for(let i in new_billentry){
		let citem = new_billentry[i]
		let source_item = []
		let fauxqty = 0
		let status = 1
		
		//获得源单（收货、拣货记录） 
		await this.selectTableData('stockbillentry','FBillNo',FBillNoPda,'row_id',citem.row_id).then(res=>{
			source_item = res[0]
		})
		
		if(source_item == undefined){
			throw('找不到源单表体记录') 
		}
		
		if(flag == '+'){
			//上架、领料出库
			fauxqty = parseFloat(source_item.fauxqty) + parseFloat(citem.fqty)
		}else{
			//删除、下架|领料出库
			fauxqty = parseFloat(source_item.fauxqty) - parseFloat(citem.fqty)
		}
		
		fauxqty = fauxqty.toFixed(this.qtyDecimal)
		if(fauxqty<0){
			throw(title+'数量小于0')
		}
		
		if(fauxqty>source_item.fqty){
			throw(title+'操作数量大于总数['+fauxqty+','+source_item.fqty+']')
		}
		
		if(fauxqty == source_item.fqty){
			status = 0 //关闭表体单体记录状态
		}
		
		try{
			//await this.exeSQL("BEGIN;")
			//更新源单（收货，拣货上架数和状态）
			await this.updateSqlData('stockbillentry',{'fauxqty':fauxqty,'status':status},'id',source_item.id)
			if(flag == '-'){
				await this.deleteTableData('stockbill','FBillNo',FBillNo)
				await this.deleteTableData('stockbillentry','FBillNo',FBillNo) 
			}
			//this.exeSQL("COMMIT;") 
		}catch(err){
			//this.exeSQL("ROLLBACK;")
			return Promise.reject(err.message)
		}
	}
},
//删除本地单据表
async deleteStockbill(FBillNo = ''){
	if(FBillNo == '' || FBillNo == undefined){
		throw('FBillNo参数错误') 
	}
	this.deleteTableData('stockbill','FBillNo',FBillNo).catch(err=>{
		throw(err.message)
	})
	this.deleteTableData('stockbillentry','FBillNo',FBillNo).catch(err=>{
		throw(err.message)
	})
},
/* 
 新增、删除 入库记录时，更新采购订单状态，收货表体数量billentry fauxqty  新增收货
 new_billentry pdpa单号（收货记录单号） 删除时
 */
async dealProcureBillData(pcode,new_billentry,flag = '+'){
	let fclose = 0 //关闭
	let _this = this
	let FBillNo = ''
	let procures = []
	let dealFlag = 0
	let show_error = ''
	
	if(this.myconfig.online){
		//在线版，直接删除
		await this.deleteTableData('stockbill','FBillNo',new_billentry)
		await this.deleteTableData('stockbillentry','FBillNo',new_billentry)
		return 
	}
	
	if(flag == '-'){
		await this.selectTableData('stockbillentry','FBillNo ',new_billentry).then(new_billentrys=>{ 
			FBillNo = new_billentry
			new_billentry = new_billentrys
		})
	}
	
	if(!new_billentry.length){
		throw('找不到表体记录')
	}
	
	if(flag == '+'){
		//判断收货（上架策略）
		await this.checkShangjiaJianhuo(new_billentry,'shangjia').catch(err=>{
			return Promise.reject(err) 
		})
	}
	
	await this.selectTableData('procure','pcode',pcode).then(res=>{
		procures = res
	})
	
	//采购订单
	for(let i in procures){
		let procure = procures[i]
		//此处用行号也行，用auto_id也行
		let new_entry = new_billentry.find(element => element.row_id == procure.row_id)
		let commit_quantity = 0 //已提交数
		let no_quantity = 0 //未提交数
		
		//提交上来的记录，在采购单表体找到
		if(new_entry != undefined){
			if(flag == '+'){
				//收货
				commit_quantity = parseFloat(procure.commit_quantity) + parseFloat(new_entry.fqty)
				no_quantity = parseFloat(procure.no_quantity) - parseFloat(new_entry.fqty)
			}else{
				//删除、收货
				commit_quantity = parseFloat(procure.commit_quantity) - parseFloat(new_entry.fqty)
				no_quantity = parseFloat(procure.no_quantity) + parseFloat(new_entry.fqty)
			}
			commit_quantity = commit_quantity.toFixed(this.qtyDecimal)
			no_quantity = no_quantity.toFixed(this.qtyDecimal)
			if(no_quantity<0){
				//throw('未提交数小于0')
				no_quantity = 0
			}
			if(no_quantity == 0){
				fclose = 1
			}
			
			if(no_quantity>procure.quantity){
				no_quantity = procure.quantity
				//throw('未提交数超过采购单数')
			}
			
			try {
				if(flag == '-'){
					//删除收货，加源单数，删本地单据表头表体记录
					//await this.exeSQL("BEGIN;")
					//判断收货单据有无被上架单据引用，有则提示
					await this.selectTableData('stockbill','source_code',FBillNo).then(check_source=>{
						if(check_source.length>0){
							throw({message:'该单据已被引用,请先删除'})
						}
					})
					
					await this.updateSqlData('procure',{commit_quantity:commit_quantity,no_quantity:no_quantity,fclose:fclose},'id',procure.id)
					await this.deleteTableData('stockbill','FBillNo',FBillNo)
					await this.deleteTableData('stockbillentry','FBillNo',FBillNo)
					//this.exeSQL("COMMIT;") 
				}else{
					//收货，减源单数
					await this.updateSqlData('procure',{commit_quantity:commit_quantity,no_quantity:no_quantity,fclose:fclose},'id',procure.id)
				}
			} catch (err) {
				if(flag == '-'){
					//this.exeSQL("ROLLBACK;")
				}
				//throw(err.message)
				this.addlog('处理入库任务表体数据',err)
				return Promise.reject(err.message)
			}
		}else{
			await this.deleteTableData('stockbill','FBillNo',FBillNo)
			await this.deleteTableData('stockbillentry','FBillNo',FBillNo)
		}
	}
},
/* 
 新增、删除 拣货记录时，更新材料申请单订单状态，收货表体数量billentry fauxqty  新增拣货
 new_billentry pdpa单号（拣货记录单号） 删除时
 */
async dealAppmaterialBillData(pcode,new_billentry,flag = '+'){
	let fclose = 0 //关闭
	let FBillNo = ''
	
	if(this.myconfig.online){
		//在线版，直接删除
		await this.deleteTableData('stockbill','FBillNo',new_billentry)
		await this.deleteTableData('stockbillentry','FBillNo',new_billentry)
		return 
	}
	
	if(flag == '-'){
		await this.selectTableData('stockbillentry','FBillNo ',new_billentry).then(new_billentrys=>{ 
			FBillNo = new_billentry
			new_billentry = new_billentrys
		})
	}
	
	//行号相同，合并后的总数
	new_billentry = Func.arraySameKeySum(new_billentry,'row_id','fqty')
	
	await this.selectTableData('appmaterial','pcode',pcode).then(appmaterials=>{
		//领料申请单
		appmaterials.forEach(appmaterial=>{
			let new_entry = new_billentry.find(element => element.row_id == appmaterial.row_id)
			let commit_quantity = 0 //已提交数
			
			if(new_entry != undefined){
				if(flag == '+'){
					//拣货
					commit_quantity = parseFloat(appmaterial.commit_quantity) + parseFloat(new_entry.fqty)
				}else{
					//删除、收货
					commit_quantity = parseFloat(appmaterial.commit_quantity) - parseFloat(new_entry.fqty)
				}
				
				commit_quantity = commit_quantity.toFixed(this.qtyDecimal)
				
				if(commit_quantity==appmaterial.quantity){
					fclose = 1
				}
				if(commit_quantity>appmaterial.quantity){
					throw('已提交数量超过申请数量')
				}
				
				this.updateSqlData('appmaterial',{commit_quantity:commit_quantity,fclose:fclose},'id',appmaterial.id).then(res=>{
					if(flag == '-'){
						//更新源单数量成功，顺便删除本地单据
						this.deleteTableData('stockbill','FBillNo',FBillNo).catch(err=>{
							throw(err)
						})
						this.deleteTableData('stockbillentry','FBillNo',FBillNo).catch(err=>{
							throw(err)
						})
					}
				}).catch(err=>{
					console.log(err)
					this.addlog('处理出库任务表体数据',err)
					throw(err.message)
				})
			}else{
				//找不到源单表体记录，则直接删除本地
				//更新源单数量成功，顺便删除本地单据
				this.deleteTableData('stockbill','FBillNo',FBillNo).catch(err=>{
					throw(err)
				})
				this.deleteTableData('stockbillentry','FBillNo',FBillNo).catch(err=>{
					throw(err)
				})
			}
		})
	})
},
/* 
  根据3种不同的二维码内容，解析出内容返回数组
  scanType 0不限 1库区货架托盘 2物料
  */
async dealQrcode(content,scanType){
	  if(content == ''){
		throw('参数错误')
	  }
	  
	  //let arr = content.split('|');
	  //let number = ''
	  let type = 0
	  let info = []
	  
	  //首字母区分，库区、货架、托盘、物料 KQ HJ WL
	  let first = content.substr(0,2)
	  let number = content.substring(2)
	  let first_arr = ['','库区','货架','托盘','物料']
	  
		if(first=='KQ'){
			type = 1
		}
		if(first=='HJ'){
			type = 2
		}
		if(first=='TP'){
			type = 3
		}
		if(first=='WL'){
			type = 4
		}
	  
	  if(type != 4){
		  if(number != '' || number != undefined){
			  if(scanType==2){
				  throw('请扫物料二维码')
			  }
			  //默认要搜索数据库
			  await this.selectTableData('shelves','number',number).then(res=>{
					info = res[0]
			  }).catch(err=>{
					throw('扫码异常['+first_arr[type]+']')
			  })
		  }
	  }else{
		  if(scanType==1){
		  		throw('请扫库区、货架、托盘二维码')
		  }
		  var inv_batch_arr = number.split('!')
		  if(!Array.isArray(inv_batch_arr)){
			  throw('扫码异常[物料]')
		  }
		  
		  await this.selectTableData('inventory_view','number',inv_batch_arr[0]).then(res=>{
		  		info = res[0]
				let cBatch_no = inv_batch_arr[1].split('-')
				info.qrNo = ''
				
				if(cBatch_no.length==1){
					info.cBatch = cBatch_no[0]
				}else if(cBatch_no.length==2){
					//带流水
					info.cBatch = cBatch_no[0]
					info.qrNo = cBatch_no[1]
				}
		  }).catch(err=>{
		  		throw('扫码异常[物料]')
		  })
	  }
	  
	  if(info==undefined){
	  	//throw('不存在二维码信息,请核实档案')
		throw('当前仓库下,不存在该二维码信息,请核实')
	  }
	return Promise.resolve({type:type,info:info})
},
//获取行号
getShelvesRow(type,stock_id){
	if(!type||!stock_id){
		throw('获取行号参数错误')
	}
	if(type==1){
		return Promise.resolve([])
	}
	let sql = "select row_number,'第'||row_number||'行' as row_str from shelves where row_number is not null and type="+type+" and warehouse_id="+stock_id+" GROUP BY row_number order by row_number"
	return new Promise((resolve, reject) => {
	  // 表格查询数据  执行查询的SQL语句
	  plus.sqlite.selectSql({
	    name: this.dbName,
	    sql: sql,
	    success(e) {
	      resolve(e);
	    },
	    fail(e) {
	      reject(e);
	    }
	  })
	})
},
//获取列号
getShelvesColumn(row_number,stock_id){
	if(!row_number||!stock_id){
		throw('获取列号参数错误')
	}
	
	let sql = "select column_number,'第'||column_number||'列' as column_str from shelves where row_number = "+row_number+" and type=2 and warehouse_id="+stock_id+" GROUP BY column_number order by column_number"
	return new Promise((resolve, reject) => {
	  // 表格查询数据  执行查询的SQL语句
	  plus.sqlite.selectSql({
	    name: this.dbName,
	    sql: sql,
	    success(e) {
	      resolve(e);
	    },
	    fail(e) {
	      reject(e);
	    }
	  })
	})
},
/* 
 获取收货单，上架进度
 pda_pcode pda单据编码
 */
//获取上架、拣货进度
getStockbillProgress(pda_pcode){
	if(!pda_pcode){
		throw('获取进度参数错误')
	}
	
	//20230729
	let _this = this
	//let sql = "SELECT COALESCE((SELECT sum(fqty) FROM stockbillentry b WHERE b.FBillNo in (SELECT FBillNo from stockbill where source_code='"+pda_pcode+"')),0) get_qty,a.total_qty FROM stockbill a WHERE a.FBillNo = '"+pda_pcode+"'"
	let sql = "SELECT COALESCE((SELECT sum(fauxqty) FROM stockbillentry where FBillNo='"+pda_pcode+"'),0) get_qty,total_qty FROM stockbill WHERE FBillNo = '"+pda_pcode+"'"
	
	return new Promise((resolve, reject) => {
	  // 表格查询数据  执行查询的SQL语句
	  plus.sqlite.selectSql({
	    name: this.dbName,
	    sql: sql,
	    success(e) {
			if(e[0] == undefined){
				resolve(0);
			}else{
				let get_qty = parseFloat(e[0].get_qty).toFixed(_this.qtyDecimal)
				let total_qty = parseFloat(e[0].total_qty)
				let rat = parseFloat(get_qty*100/total_qty).toFixed(0)
				if(isNaN(rat)){
					rat = 0
				}
				resolve({rat:rat,get_qty:get_qty,total_qty:total_qty});
			}
	    },
	    fail(e) {
	      reject(e);
	    }
	  })
	})
},
//检查本地未回传单据
checkNoBackStockBill(order_type_arr = []){
	if(order_type_arr.length == 0){
		//throw('核实本地单据同步状态参数错误')
		return Promise.reject('核实本地单据同步状态参数错误')
	}
	
	let sql = "select id from stockbill where syn_status = 0 and order_type in ("+order_type_arr.join(',')+") "
	return new Promise((resolve, reject) => {
	  // 表格查询数据  执行查询的SQL语句
	  plus.sqlite.selectSql({
	    name: this.dbName,
	    sql: sql,
	    success(e) {
		  if(e.length>0){
			  //存在未同步单据
			  //reject('存在未回传单据，请先回传');
			  resolve(true);
		  }else{
			  resolve(true);
		  }
	    },
	    fail(e) {
	      reject(e);
	    }
	  })
	})
},
//新增盘点明细，重复的,先删除，后新增
async dealCheckItem(FBillNo = '',billentrys = []){
	return new Promise(async(resolve, reject) => {
		if(FBillNo == ''||billentrys.length == 0){
			return reject('FBillNo、billentrys参数错误')
		}
		
		//this.exeSQL('BEGIN;')
		try{
			//await this.deleteCheckItem(FBillNo,billentrys)
			for (const item of billentrys) {
				var sql = `select * from check_kc_item where inv_id='${item.inv_id}' and shelves_id=${item.shelves_id} and cBatch='${item.cBatch}' and FBillNo='${FBillNo}'`;
				let isnew = false
				let row = []
				await this.selectSQL(sql).then(res=>{
					if(res.length>0){
						row = res[0]
					}else{
						isnew = true
					}
				})
				
				if(isnew){
					await this.addSaveData('check_kc_item',{
						"FBillNo":FBillNo,
						"inv_id":item.inv_id,
						"inv_number":item.number==undefined?item.cInvCode:item.number,
						"inv_name":item.name,
						"inv_specification":item.specification,
						"inv_unit":item.unit,
						"inv_unit_code":item.unit_code,
						"store_unit":item.store_unit,
						"store_unit_code":item.store_unit_code,
						"shelves_id":item.shelves_id,
						"shelves_name":item.shelves_name,
						"kc_qty":item.kc_quantity==undefined?0:item.kc_quantity,
						"kc_auxqty":item.kc_store_quantity==undefined?0:item.kc_store_quantity,
						"check_qty":item.real_quantity,
						"check_auxqty":item.real_store_quantity,
						"cBatch":item.cBatch,
						"scan_flag":1,
						"isnew":1,
						"scan_datetime":Func.getDateTime('todaytime')
					})
					//更新表头总数
					//await this.exeSQL("update check_kc set totalnum=(select COALESCE(sum(check_qty),0) from check_kc_item where FBillNo='"+FBillNo+"') where FBillNo='"+FBillNo+"'")
					await this.exeSQL("update check_kc set totalnum=totalnum+1 where FBillNo='"+FBillNo+"'")
				}else{
					//更新扫描状态和扫描数量
					await this.updateSqlData('check_kc_item',{
						'check_qty':item.real_quantity,
						'check_auxqty':item.real_store_quantity,
						'scan_flag':1,
						"scan_datetime":Func.getDateTime('todaytime')
						},'id',row.id)
				}
			}
			
			//this.exeSQL("COMMIT;")
			return resolve()
		}catch(e){
			//this.exeSQL("ROLLBACK;")
			if(e.message!=undefined){
				return reject(e.message)
			}else{
				return reject(e)
			}
		}
	})
},
//新增调拨明细，重复的,先删除，后新增
async dealAllotItem(FBillNo = '',billentrys = []){
	return new Promise(async(resolve, reject) => {
		if(FBillNo == ''||billentrys.length == 0){
			return reject('FBillNo、billentrys参数错误')
		}
		
		//this.exeSQL('BEGIN;')
		try{
			//await this.deleteAllotItem(FBillNo,billentrys)//先清空之前
			for (const item of billentrys) {
				var sql = `select * from allot_item where inv_id='${item.inv_id}' and shelves_id=${item.shelves_id} and cBatch='${item.cBatch}' and FBillNo='${FBillNo}'`;
				if(item.to_shelves_id!=''){
					sql += ` and to_shelves_id=${item.to_shelves_id}`
				}
				
				let isnew = false
				let row = []
				await this.selectSQL(sql).then(res=>{
					if(res.length>0){
						row = res[0]
					}else{
						isnew = true
					}
				})
				
				if(isnew){
					await this.addSaveData('allot_item',{
						"kc_id":item.kc_id,
						"FBillNo":FBillNo,
						"inv_id":item.inv_id,
						"inv_number":item.number,
						"inv_name":item.name,
						"inv_specification":item.specification,
						"inv_unit":item.unit,
						"inv_unit_code":item.unit_code,
						"store_unit":item.store_unit,
						"store_unit_code":item.store_unit_code,
						"shelves_id":item.shelves_id,
						"cBatch":item.cBatch,
						"shelves_name":item.shelves_name,
						"to_shelves_id":item.to_shelves_id,
						"to_shelves_name":item.to_shelves_name,
						"kc_qty":item.kc_quantity,
						"kc_auxqty":item.kc_store_quantity==undefined?0:item.kc_store_quantity,
						"allot_qty":item.real_quantity,
						"allot_auxqty":item.real_store_quantity
					})
				}else{
					//更新数量
					await this.updateSqlData('allot_item',{
						'kc_qty':item.kc_quantity,
						'kc_auxqty':item.kc_store_quantity==undefined?0:item.kc_store_quantity,
						'allot_qty':item.real_quantity,
						"allot_auxqty":item.real_store_quantity,
						},'id',row.id)
				}
			}
			
			//更新表头总数
			await this.exeSQL("update allot set totalnum=ROUND((select COALESCE(sum(allot_qty),0) from allot_item where FBillNo='"+FBillNo+"'),"+this.qtyDecimal+") where FBillNo='"+FBillNo+"'")
			//await this.exeSQL("COMMIT;")
			return resolve()
		}catch(e){
			//this.exeSQL("ROLLBACK;")
			this.addlog('添加调拨明细',e)
			if(e.message!=undefined){
				return reject(e.message)
			}else{
				return reject(e)
			}
		}
	})
},
async deleteCheckItem(FBillNo = '',billentrys){
	let items = []
	await this.selectTableData('check_kc_item','FBillNo',FBillNo).then(res=>{
		items = res
	})
	
	if(items.length == 0){
		return
	}
				
	for (const billentry of billentrys) {
	  let check = items.find(ele => ele.inv_number == billentry.number&&ele.shelves_id==billentry.shelves_id&&ele.cBatch==billentry.cBatch)
		if(check!=undefined){
			//存在，删除
			await this.deleteTableData('check_kc_item','id',check.id).catch(err=>{
				throw(err)
			})
		}
	}
},
async deleteAllotItem(FBillNo = '',billentrys){
	//////////////////20240105
	if(FBillNo!=''){
		this.deleteTableData('allot_item','FBillNo',FBillNo)
		.catch(err=>{
			throw(err.message)
		})
	}
	/////////////////////////
	
	//最新的表体billentrys
	let items = []//之前历史表体
	//取出所有调拨明细
	await this.selectTableData('allot_item','FBillNo',FBillNo).then(res=>{
		items = res
	})
	
	if(items.length == 0){
		return 
	}
	
	//2者进行对比
	for (const billentry of billentrys) {
	  let check = items.find(ele => ele.inv_number == billentry.number&&ele.shelves_id==billentry.shelves_id&&ele.to_shelves_id==billentry.to_shelves_id&&ele.cBatch == billentry.cBatch)
		console.log(check)
		if(check!=undefined){
			//存在，删除
			this.deleteTableData('allot_item','id',check.id)
			.then(res=>{
				console.log(res)
			})
			.catch(err=>{
				throw(err.message)
			})
	  }
	}
},
//总回传数据，首页,默认离线版0
async backSynAllData(user){
	return new Promise(async(resolve, reject) => {
		let stockbill_rows = [];
		let stockbillentry_rows = []
		let check_inventory_rows = []
		let allot_rows = []
		let data_flag = false
		
		//this.exeSQL("BEGIN;")
		//出入库单据表体,注意，表头的auto_id已作废,所以重命名为a_auto_id，采用表体的auto_id
		var sql = "select a.*,b.*,a.id a_id,b.id b_id,a.auto_id a_auto_id from stockbillentry b left join stockbill a on a.FBillNo = b.FBillNo where a.status=1 and a.syn_status=0 and userid='"+user.userid+"' order by b.id";//and a.order_type not in (2)
		await this.selectSQL(sql).then(res=>{
			stockbillentry_rows = res
			if(res.length>0){
				data_flag = true
			}
		})
		
		var asql = "select a.*,b.*,a.id a_id,b.id b_id from allot_item b left join allot a on a.FBillNo = b.FBillNo where a.status=1 and a.syn_status=0 and userid='"+user.userid+"' order by b.id";
		await this.selectSQL(asql).then(res=>{
			allot_rows = res
			if(res.length>0){
				data_flag = true
			}
		})
 		
		var csql = "select a.*,b.*,a.id a_id,b.id b_id from check_kc_item b left join check_kc a on a.FBillNo = b.FBillNo where a.status=1 and a.syn_status=0 and b.scan_flag=1 and userid='"+user.userid+"' order by b.id";
		await this.selectSQL(csql).then(res=>{
			check_inventory_rows = res
			if(res.length>0){
				data_flag = true
			}
		})
		
		if(data_flag){
			//同步回服务器
			Api.addstockbills(stockbillentry_rows,allot_rows,check_inventory_rows).then(res => {
				if(res.data.code == 1){
					stockbillentry_rows.forEach(item=>{
						//更新本地单据状态
						this.exeSQL("UPDATE stockbill SET syn_status = '1' WHERE id="+item.a_id)
					})
					allot_rows.forEach(item=>{
						//更新本地调拨单状态
						this.exeSQL("UPDATE allot SET syn_status = '1' WHERE id="+item.a_id)
					})
					check_inventory_rows.forEach(item=>{
						//更新本地调拨单状态
						this.exeSQL("UPDATE check_kc SET syn_status = '1' WHERE id="+item.a_id)
					})
					if(!this.myconfig.online){
						//离线版
						uni.setStorageSync('backDataFlag',true)//有回传，则加上回传标识，做单前，得先同步
					}
					//this.exeSQL("COMMIT;")
					return resolve()
				}else if(res.data.code == 0){
					return reject(res.data.msg)
				}else{
					if(res.statusCode == 500){
						return reject('服务器异常')
					}
				}
			}).catch(err=>{
				//接口异常
				return reject(err)
			})
		}else{
			return reject('暂无可回传单据')
		}
	})
},
//对应pctype的类型 单个
async backSynData(type='stockbill',bill = {},pdatype = 0){
	return new Promise(async(resolve, reject) => {
		if(JSON.stringify(bill) === '{}'){
			return reject('bill参数错误')
		}
		
		//表体数据
		let billentrys = []
		let table_bill_name = 'stockbill'
		if(type == 'stockbill'){
			 //本地出入单据明细
			await this.selectTableData('stockbillentry','FBillNo',bill.FBillNo).then(res=>{
			 	billentrys = res;
			});
		}else if(type == 'checkbill'){
			//盘点单据
			table_bill_name = 'check_kc'
			//只同步已扫描的
			await this.selectTableData('check_kc_item','FBillNo',bill.FBillNo,'scan_flag',1).then(res=>{
			 	billentrys = res;
			});
		}else if(type == 'allotbill'){
			//调拨单据
			table_bill_name = 'allot'
			await this.selectTableData('allot_item','FBillNo',bill.FBillNo).then(res=>{
			 	billentrys = res;
			});
		}
		 
		 if(!billentrys.length){
			 return reject('表体不能为空')
		 }
		 
		 //过滤特殊字符
		 if(bill.remark!=undefined){
			bill.remark = Func.htmlEncode(bill.remark)
		 }
		 if(bill.a_remark!=undefined){
		 	bill.a_remark = Func.htmlEncode(bill.a_remark)
		 }
		 
		 uni.showLoading({
		 	mask:true
		 })
		 //访问服务器接口
		 Api.addstockbill(bill,billentrys,pdatype).then(res=>{
			 uni.hideLoading()
			 if(!res.data.code){
				 if(res.data.msg!=undefined){
					 return reject(res.data.msg)
				 }else{
					 return reject('服务器异常','error')
				 }
			 }else{
				 //返回成功，更新单据同步状态
				let conditon = {'syn_status':1}
				if(type == 'checkbill'){
					//同步同时更新2个状态
					conditon = {'syn_status':1,'status':1}
				}
				this.updateSqlData(table_bill_name,conditon,'FBillNo',bill.FBillNo).then(()=>{
					//uni.setStorageSync('backDataFlag',true)//有回传，则加上回传标识，做单前，得先同步
					return resolve('回传成功')
				}).catch(err=>{
					console.log(err)
				})
			 }
		 }).catch(err=>{
			 uni.hideLoading()
			 this.addlog('回传数据',err)
			 if(err.message!=undefined){
				 return reject(err.message)
			 }else{
				 return reject(err)
			 }
		 })
	})
},
//同步本地未同步状态的单据，保证和pc状态一致
async synPdaPcOrderStatus(user){
	let stockbill_rows = [];
	let check_inventory_rows = []
	let allot_rows = []
	let data_flag = false
	
	//this.exeSQL("BEGIN;")
	//出入库单据表体,注意，表头的auto_id已作废,所以重命名为a_auto_id，采用表体的auto_id
	var sql = "select id,FBillNo from stockbill where status=1 and syn_status=0 and userid='"+user.userid+"'";
	await this.selectSQL(sql).then(res=>{
		stockbill_rows = res
		if(res.length>0){
			data_flag = true
		}
	})
	
	var asql = "select id,FBillNo from allot where status=1 and syn_status=0 and userid='"+user.userid+"'";
	await this.selectSQL(asql).then(res=>{
		allot_rows = res
		if(res.length>0){
			data_flag = true
		}
	})
	
	var csql = "select id,FBillNo from check_kc where status=1 and syn_status=0 and userid='"+user.userid+"'";
	await this.selectSQL(csql).then(res=>{
		check_inventory_rows = res
		if(res.length>0){
			data_flag = true
		}
	})
	
	if(data_flag){
		//判断服务器单据
		Api.synPdaPcOrderStatus(stockbill_rows,allot_rows,check_inventory_rows).then(res => {
			if(res.data.code == 1){
				if(res.data.data.bills.length>0){
					res.data.data.bills.forEach(id=>{
						//更新本地单据状态
						this.exeSQL("UPDATE stockbill SET syn_status = '1' WHERE id="+id)
						this.addlog('首页同步,纠正单据状态',JSON.stringify(stockbill_rows))
					})
				}
				if(res.data.data.allots.length>0){
					res.data.data.allots.forEach(id=>{
						//更新本地单据状态
						this.exeSQL("UPDATE allot SET syn_status = '1' WHERE id="+id)
						this.addlog('首页同步,纠正调拨单状态',JSON.stringify(allot_rows))
					})
				}
				if(res.data.data.checks.length>0){
					res.data.data.checks.forEach(id=>{
						//更新本地盘点单据状态 
						this.exeSQL("UPDATE check_kc SET syn_status = '1' WHERE id="+id)
						this.addlog('首页同步,纠正盘点单状态',JSON.stringify(check_inventory_rows))
					})
				}
			}
		})
	}
},
//校验上架策略和拣货策略 shangjia、jianhuo 单据类型order_type  17直接上
async checkShangjiaJianhuo(inv_data_arr,type = 'shangjia'){
	//最新的表体billentrys
	if(!inv_data_arr.length||inv_data_arr==''||inv_data_arr.length==undefined){
		throw('找不到inv_data_arr记录')
	}
	
	for(let inv of inv_data_arr){
		let number = ''
		let shelves_type = '' //1库区，2货架
		if(inv.inv_number!=undefined){
			number = inv.inv_number
		}else{
			number = inv.number
		}
		if(inv.shelves_type!=undefined){
			shelves_type = inv.shelves_type
		}else{
			if(inv.shelves_id!=undefined){
				await this.selectTableData('shelves','id',inv.shelves_id).then(res=>{
					shelves_type = res[0].type
				})
			}
			if(shelves_type==''||shelves_type==undefined){
				throw('货架类型获取失败,shelves_type没赋值')
			}
		}
		
		if(inv.ifshangjia!=undefined){
			//自带属性过来，不用查询数据库
			if(type=='shangjia'&&inv.ifshangjia&&inv.shelves_type!=inv.ifshangjia){
				let shangjia_tip = inv.ifshangjia==1?'上库区':'上货架'
				throw('物料'+inv.name+'上架策略不匹配['+shangjia_tip+'],请核实物料档案')
			}
			if(type=='jianhuo'&&inv.ifjianhuo==1){
				throw('物料'+inv.name+'拣货策略不匹配,请核实物料档案')
			}
		}else{
			await this.selectTableData('inventory_view','number',number).then(res=>{
				if(res[0] == undefined){
					throw('不存在物料编码'+number)
				}
				
				if(type=='shangjia'){
					if(res[0].ifshangjia&&shelves_type!=res[0].ifshangjia){//一定要上架2、上库区1
						let shangjia_tip = res[0].ifshangjia==1?'上库区':'上货架'
						throw('物料'+res[0].name+'上架策略不匹配['+shangjia_tip+'],请核实物料档案')
					}
				}else{
					//拣货
					if(res[0].ifjianhuo){//一定要经过拣货，也就是要下领料申请单
						throw('物料'+res[0].name+'拣货策略不匹配,请核实物料档案')
					}
				}
			})
		}
	}
},
//校验货架物料分类策略 用于上架操作 eg:某某某货架、库区，只能存放酒精
//放数组，单个的也放进数组
async checkShelvesInvclass(inv_data_arr,shelves_id = 0){
	return new Promise(async(resolve, reject) => {
		if(this.myconfig.syn_shelvesInvclass!=1){//不是1，就跳过
			resolve() 
		}
		
		//最新的表体billentrys
		if(!inv_data_arr.length||inv_data_arr.length==undefined){
			reject('找不到inv_data_arr记录')
		}
		
		for(let inv of inv_data_arr){
			let to_check_shelves_id = 0
			if(shelves_id>0){
				to_check_shelves_id = shelves_id
			}else{
				if(inv.shelves_id>0){
					to_check_shelves_id = inv.shelves_id
				}
			}
			
			//没有货架则跳过，
			if(!to_check_shelves_id){
				continue
			}
			
			//物料分类空,根据物料编码去找
			if(inv.classification_id==undefined||inv.classification_id==''){
				await this.selectTableData('inventory_view','number',inv.number).then(res=>{
					inv.classification_id = res[0].classification_id
				})
			}
			
			if(inv.classification_id==undefined||inv.classification_id==''){
				//如果再次空
				reject('物料分类策略已开启,物料'+inv.name+'物料分类为空')
			}
			
			let shelves_arr = []
			await this.selectTableData('shelvesInvclass','shelves_id',to_check_shelves_id).then(res=>{
				res.forEach(item=>{
					shelves_arr.push(item.classification_id)
				})
			})
			
			//找不多对应的货架设置，也跳过
			if(!shelves_arr.length||shelves_arr.length==undefined){
				continue
			}
			
			if(shelves_arr.length){
				if(!Func.inArray(inv.classification_id,shelves_arr)){
					reject('物料'+inv.name+'不符合货架物料分类策略,请核实')
				}
			}
		}
		resolve()
	})
},
//记录操作日志
addlog(action,result){
	if(result.message!=undefined){
		result = result.message
	}
	let no_add_log_msg = ['后台存在未处理单据，请先处理','暂无可回传单据']
	if(no_add_log_msg.includes(result)){
		return 
	}
	
	let userid = ''
	let username = ''
	
	if(uni.getStorageSync('username')=='admin'){
		userid = 'admin'
		username = 'admin'
	}else{
		userid = uni.getStorageSync('user').userid
		username =uni.getStorageSync('user').username
	}
	
	let data = {
		'userid':userid,
		'username':username,
		'action':action,
		'url':Func.getNowPagePath(),
		'result':Func.rpXiegan(result),//去斜杆
		'create_date':Func.getDateTime('todaytime'),
		'uuid':uni.getStorageSync('uuid')
	}

	this.addSaveData('action_log',data)
},
//针对操作库存上架、出库、1条库存被多次使用的情况，加多个验证
//同条库存记录合并总数，然后，验证即时库存数，看是否会超出
//billentry 表体明细，b_remark存放kc_id值
async checkMergeKcSum(billentry = []){
	let merge_kc_arr = Func.checkSameShelvesInvOut(billentry,'array','kc_number')
	for(let merge of merge_kc_arr){
		if(merge.kc_id!=''){
			let kc_id = parseInt(merge.kc_id)
			if(!isNaN(kc_id)){
				//有库存，核实库存总数，看上架数
				let merge_sum = merge.fqtys.toFixed(this.qtyDecimal)
				await this.selectTableData('kc','kc_id',kc_id).then(res=>{
					if(merge_sum>res[0].iQuantity){
						throw(merge.inv_name+'操作数量'+merge_sum+'大于库存,请核实')
					}
				})
			}
		}
	}
},
//验证单据pc端是否处理失败，是则撤销同步
//对应pctype的类型
async unSynData(type='stockbill',FBillNo){
	return new Promise(async(resolve, reject) => {
		if(FBillNo== ''||FBillNo==undefined){
			return reject('单号不能为空')
		}
		
		let table_bill_name = 'stockbill'
		if(type == 'stockbill'){
			 //本地出入单据明细
		}else if(type == 'checkbill'){
			//盘点单据
			table_bill_name = 'check_kc'
			
		}else if(type == 'allotbill'){
			//调拨单据
			table_bill_name = 'allot'
		}
		
		 uni.showLoading({
		 	mask:true
		 })
		 //访问服务器接口
		 Api.unSyn(FBillNo).then(res=>{
			 uni.hideLoading()
			 if(!res.data.code){
				 if(res.data.msg!=undefined){
					 return reject(res.data.msg)
				 }else{
					 return reject('服务器异常','error')
				 }
			 }else{
				 //返回成功，更新单据同步状态
				let conditon = {'syn_status':0}
				if(type == 'checkbill'||type == 'allotbill'){
					//同步同时更新2个状态
					conditon = {'syn_status':0,'status':0}
				}
				this.updateSqlData(table_bill_name,conditon,'FBillNo',FBillNo).then(()=>{
					return resolve('撤销成功')
				})
			 }
		 }).catch(err=>{
			 uni.hideLoading()
			 if(err.message!=undefined){
				 return reject(err.message)
			 }else{
				 return reject(err)
			 }
		 })
	})
},
//回传日志到pc端
async synActionLog(userid){
	if(userid==undefined)return 
	return new Promise(async(resolve, reject) => {
		let user = uni.getStorageSync('user');
		let data = []
		await this.selectDataList('action_log',{syn_status:0,userid:userid}).then(res=>{
			data = res
		})
		if(data.length>0){
			 //访问服务器接口
			 Api.synActionLog(data).then(res=>{
				 if(res.data.code == 1){
					//返回成功，更新单据同步状态
					data.forEach(item=>{
						this.updateSqlData('action_log',{'syn_status':1},'id',item.id)
					})
				 }
			 }).catch(err=>{
				 this.addlog('回传操作日志',err)
			 })
		 }
	})
},
//点同步按钮，判断有无待回传数据，针对某些单据类型有无待回传 
checkExistStockbillNosynByType(type_arr = [],field='*'){
	if(type_arr.length==0){
		throw('单据类型参数错误')
	}
	
	let sql = `select ${field} from stockbill where status=1 and syn_status=0 and userid='${uni.getStorageSync('user').userid}' and order_type in (${type_arr.join(',')})`
	this.selectSQL(sql).then(res=>{
		console.log(res)
	}).catch(err=>{
		this.addlog('首页同步按钮',err)
		throw('数据表未创建')
	})
	
	return new Promise((resolve, reject) => {
	  // 表格查询数据  执行查询的SQL语句
	  plus.sqlite.selectSql({
	    name: this.dbName,
	    sql: sql,
	    success(e) {
			console.log(e)
	      resolve(e);
	    },
	    fail(el) {
	      reject(el);
	    }
	  })
	})
},
//获取登录用户仓库下的物料位置
async getKcShelvesIdsByInvNumber(inv_number,cBatch = ''){
	return new Promise((resolve, reject) => {
		if(inv_number){
			if(this.myconfig.online){
				//在线
				this.selectTableData('kc','inv_number',inv_number,'cBatch',cBatch).then(res=>{
					let shelves_id_arr = res.map(item=>{
						return item.shelves_id
					})
					return resolve(shelves_id_arr)
				})
			}else{
				//离线
				var sql = `select shelves_id from kc where warehouse_id='${uni.getStorageSync('user').stock_id}' and cInvCode='${inv_number}'`;
				this.selectSQL(sql).then(res=>{
					let shelves_id_arr = res.map(item=>{
						return item.shelves_id
					})
					return resolve(shelves_id_arr)
				})
			}
		}
	})
},
//获得wms平台，拣货单、收货单
async synPickShouhuoOrder(bills,order_type=2){
	//取出所有单据
	let stockbills = []
	await this.selectTableData('stockbill','order_type',order_type).then(res=>{
		stockbills = res
	})

	//2者进行对比
	for (const bill of bills) {
	  let check = stockbills.find(ele => ele.FBillNo == bill.order_code)
		if(check==undefined){
			//不存在，新增表头
			let head = bill
			let body = bill.details
			delete bill.details;
			
			//表头
			this.addSaveData('stockbill',head)
			
			//表体
			for (const billentry of body) {
				this.addSaveData('stockbillentry',billentry)
			}
	  }
	}
},
}